# -*- coding: utf-8 -*-
"""
Created on Sat Apr 22 15:57:57 2023

@author: simsh
"""

#!/usr/bin/python3

# Switch to a backend that doesn't need X

import matplotlib.pyplot as plt
import pandas as pd
import math
#import SMART

FIXED = 0
EXPO = 1

def plotUtilQuad(scenario_df, core_count):
    plt.rcParams['figure.figsize'] = [16, 16]
    fig = plt.figure()
    fig.tight_layout(rect=[0, 0.03, 1, 0.90])
    #figure, axis = plt.subplots(2, 2, figsize=(12, 12))
    #plt.rcParams['figure.figsize'] = [16, 16]
    for i in range(1, 5):
        #etc = fig.add_subplot(2,2,i)
        taskUtilRange=TASK_UTIL_RANGES[i-1]
        #print("Calling add_plot.")
        etc = fig.add_subplot(2,2,i)
        util_df = scenario_df[(scenario_df['per_task_util_min'] == taskUtilRange[0]) &
                              (df['per_task_util_max'] == taskUtilRange[1])]
        fileName = add_plot(etc, util_df, coreCount, taskUtilRange[0], taskUtilRange[1])
    #fig.show()
    fig.savefig(FOLDER_OUT + fileName + ".pdf")
    fig.clf()


def add_plot(target, scenario_df, core_count, taskUtilMin, taskUtilMax):
    minTotalUtil = 3*core_count /4
    maxTotalUtil = core_count*2
    ticks=[]
    for j in range(math.floor(minTotalUtil), maxTotalUtil):
        ticks.append(j)
    #plt.set_xticks(ticks)
    #what are the utilization points we need to plot?
    util=[]
    j=0
    num_bins = math.ceil((maxTotalUtil-minTotalUtil)/BIN_SIZE)
    while j  < num_bins:
    #while j * BIN_SIZE <= maxTotalUtil:
        util.append(minTotalUtil+(j+.5)*BIN_SIZE)
        j += 1
    best_rsa = ''
    successRates = []
    j = 0
    while j  < num_bins:
    #while j * BIN_SIZE <= maxTotalUtil:
        # I'll have to clean up column names manually
        successRates.append(scenario_df[str(j)].values[0])
        j += 1
    target.plot(util, successRates, linestyle='solid')
    target.set_ylim(0, 1.02)
    target.set_xlim(3*coreCount/4, 2 * coreCount)
    target.set_xlabel('Utilization')
    target.set_ylabel('Schedulability Ratio')
    # plt.legend(algoName)
    rsa = scenario_df['RSA'].values[0]
    rsa_string = str(round(rsa, 2))
    #rsa_string = str(round(scenario_df['rsa'].values[0], 2))

    # give graph a title and save
    full_header, name = write_header_and_name(coreCount, taskUtilMin, taskUtilMax, expected_score, slope, rsa_string)
    target.set_title(full_header)
    return name


def write_header_and_name(coreCount, minTaskUtil, maxTaskUtil, expected_score, slope, best_rsa):

    coreHeader=str(str(coreCount) + " Cores")
    distrib_header = "f(1)=" + str(expected_score) + ", slope=" + "{:.2f}".format(slope)
    if score_distro == FIXED:
        distrib_header = distrib_header + ", fixed"
    elif score_distro == EXPO:
        distrib_header = distrib_header + ", expo"
    util_header="Task Util. ~ U(" + str(minTaskUtil) + ", " + str(maxTaskUtil) + ")"
    rsa_header = "RSA: " + best_rsa
    full_header="\n" + coreHeader + ", " + util_header + "\n" + distrib_header + "\n" + rsa_header + ", Timeout: " + str(TIMEOUT)
    name = " ".join([coreHeader, distrib_header])
    return full_header, name

FOLDER_OUT = "8CoreQuads/"
#FILE_IN = "May-10-1734-50Samples.csv"
FILE_IN = "May-16-1958-50Samples-oneAtATime.csv"

#Apr 22 2100 uses bin size 0.2?
BIN_SIZE = 0.25
#BIN_SIZE = .10

#TASK_UTIL_RANGES=[(0, .4), (0, 1)]
TASK_UTIL_RANGES=[(0, .4), (.3, .7), (.6, 1), (0, 1)]
EXPECTED_SCORES = [0.35, 0.55, 0.75]
#EXPECTED_SCORES = [0.4]
TIMEOUT = 60

df=pd.read_csv(FILE_IN)

# crazy nested for loop because I want to look at lines matching a single scenario at once
# I can't guarantee the order in which results will be in file.
for coreCount in [8]:
    for expected_score in EXPECTED_SCORES:
        for score_distro in [FIXED, EXPO]:
            for slope in (0, 0.15, 0.30):
                scenario_df = df[
                    (df['core_count'] == coreCount) &
                    (df['expected_score'] == expected_score) &
                    (df['slope'] == slope) &
                    (df['score_distro'] == score_distro) &
                    (df['timeout'] == TIMEOUT)
                    ]
                # if we don't have any scenarios with current parameters
                if scenario_df.shape[0] == 0:
                    continue

                plotUtilQuad(scenario_df, coreCount)